package job

import (
	"encoding/json"
	"fmt"
	"gin/common/alarm"
	"gin/common/function"
	"gin/common/queue"
	"gin/core"
	"gin/model"
	"github.com/reugn/go-quartz/quartz"
	"github.com/syyongx/php2go"
	"gorm.io/gorm/utils"
	"strconv"
	"time"
)

type Comment struct {
	Uid       int    `json:"uid"`
	Content   string `json:"content"`
	Xueqiuuid int    `json:"xueqiuuid"`
}

type XueqiuComment struct {
	Count    int                 `json:"count"`
	Statuses []XueqiuCommentList `json:"statuses"`
}

type XueqiuCommentList struct {
	Id        int    `json:"id"`
	Text      string `json:"text"`
	CreatedAt string `json:"created_at"`
}

// PrintJob implements the quartz.Job interface.
type Xueqiu struct {
	Desc   string
	Signal chan bool
}

type AutoGenerated struct {
	Count    int `json:"count"`
	Statuses []struct {
		ID              int         `json:"id"`
		UserID          int64       `json:"user_id"`
		Source          string      `json:"source"`
		Title           string      `json:"title"`
		CreatedAt       int64       `json:"created_at"`
		RetweetCount    int         `json:"retweet_count"`
		ReplyCount      int         `json:"reply_count"`
		FavCount        int         `json:"fav_count"`
		Truncated       bool        `json:"truncated"`
		CommentID       int         `json:"commentId"`
		RetweetStatusID int         `json:"retweet_status_id"`
		SymbolID        interface{} `json:"symbol_id"`
		Description     string      `json:"description"`
		Type            string      `json:"type"`
		SourceLink      string      `json:"source_link"`
		EditedAt        interface{} `json:"edited_at"`
		User            struct {
			Subscribeable       bool        `json:"subscribeable"`
			CommonCount         int         `json:"common_count"`
			Remark              interface{} `json:"remark"`
			RecommendReason     interface{} `json:"recommend_reason"`
			Domain              interface{} `json:"domain"`
			Type                string      `json:"type"`
			FriendsCount        int         `json:"friends_count"`
			Location            interface{} `json:"location"`
			Description         string      `json:"description"`
			ID                  int64       `json:"id"`
			URL                 interface{} `json:"url"`
			Status              int         `json:"status"`
			BlogDescription     interface{} `json:"blog_description"`
			StocksCount         int         `json:"stocks_count"`
			Recommend           interface{} `json:"recommend"`
			StColor             string      `json:"st_color"`
			Intro               interface{} `json:"intro"`
			FollowMe            bool        `json:"follow_me"`
			AllowAllStock       bool        `json:"allow_all_stock"`
			StockStatusCount    interface{} `json:"stock_status_count"`
			ScreenName          string      `json:"screen_name"`
			Following           bool        `json:"following"`
			Gender              string      `json:"gender"`
			Blocking            bool        `json:"blocking"`
			Profile             string      `json:"profile"`
			Verified            bool        `json:"verified"`
			FollowersCount      int         `json:"followers_count"`
			VerifiedType        int         `json:"verified_type"`
			Province            string      `json:"province"`
			City                string      `json:"city"`
			StatusCount         int         `json:"status_count"`
			LastStatusID        int         `json:"last_status_id"`
			VerifiedDescription interface{} `json:"verified_description"`
			Step                string      `json:"step"`
			DonateCount         int         `json:"donate_count"`
			Name                interface{} `json:"name"`
			VerifiedInfos       []struct {
				Data         interface{} `json:"data"`
				VerifiedType string      `json:"verified_type"`
				VerifiedDesc string      `json:"verified_desc"`
			} `json:"verified_infos"`
			GroupIds         interface{} `json:"group_ids"`
			VerifiedRealname bool        `json:"verified_realname"`
			NamePinyin       interface{} `json:"name_pinyin"`
			ScreennamePinyin interface{} `json:"screenname_pinyin"`
			PhotoDomain      string      `json:"photo_domain"`
			LiveInfo         struct {
			} `json:"live_info"`
			ProfileImageURL string `json:"profile_image_url"`
		} `json:"user"`
		RetweetedStatus        interface{}   `json:"retweeted_status"`
		Answers                interface{}   `json:"answers"`
		Rqtype                 interface{}   `json:"rqtype"`
		Rqid                   int           `json:"rqid"`
		Target                 string        `json:"target"`
		Fragment               interface{}   `json:"fragment"`
		Blocked                bool          `json:"blocked"`
		Blocking               bool          `json:"blocking"`
		TopicPic               interface{}   `json:"topic_pic"`
		TopicSymbol            interface{}   `json:"topic_symbol"`
		TopicTitle             interface{}   `json:"topic_title"`
		TopicDesc              interface{}   `json:"topic_desc"`
		DonateCount            int           `json:"donate_count"`
		DonateSnowcoin         int           `json:"donate_snowcoin"`
		Liked                  bool          `json:"liked"`
		ViewCount              int           `json:"view_count"`
		WeixinRetweetCount     int           `json:"weixin_retweet_count"`
		Mark                   int           `json:"mark"`
		Card                   interface{}   `json:"card"`
		Favorited              bool          `json:"favorited"`
		FavoritedCreatedAt     interface{}   `json:"favorited_created_at"`
		Offer                  interface{}   `json:"offer"`
		Score                  interface{}   `json:"score"`
		Controversial          bool          `json:"controversial"`
		FundxHold              interface{}   `json:"fundxHold"`
		Tips                   interface{}   `json:"tips"`
		StockCorrelation       []interface{} `json:"stockCorrelation"`
		FirstImg               interface{}   `json:"firstImg"`
		Reward                 bool          `json:"reward"`
		LongTextForIOS         bool          `json:"longTextForIOS"`
		RawTitle               string        `json:"rawTitle"`
		TagStr                 string        `json:"tagStr"`
		CanEdit                bool          `json:"canEdit"`
		TimeBefore             string        `json:"timeBefore"`
		Expend                 bool          `json:"expend"`
		TopicPicThumbnailSmall interface{}   `json:"topic_pic_thumbnail_small"`
		TopicPicThumbnail      interface{}   `json:"topic_pic_thumbnail"`
		TopicPicHeadOrPad      interface{}   `json:"topic_pic_headOrPad"`
		TagsForWeb             string        `json:"tagsForWeb"`
		MetaKeywords           string        `json:"meta_keywords"`
		PaidMention            interface{}   `json:"paid_mention"`
		RewardCount            int           `json:"reward_count"`
		RewardAmount           int           `json:"reward_amount"`
		RewardUserCount        int           `json:"reward_user_count"`
		TalkCount              int           `json:"talk_count"`
		LikeCount              int           `json:"like_count"`
		VideoInfo              interface{}   `json:"video_info"`
		QuoteCards             interface{}   `json:"quote_cards"`
		PromotionPic           interface{}   `json:"promotion_pic"`
		PromotionURL           interface{}   `json:"promotion_url"`
		PromotionID            int           `json:"promotion_id"`
		MarkDesc               interface{}   `json:"mark_desc"`
		PicSizes               []interface{} `json:"pic_sizes"`
		CoverPicSize           interface{}   `json:"cover_pic_size"`
		OrderID                int           `json:"order_id"`
		Tags                   []interface{} `json:"tags"`
		StatusIndustry         interface{}   `json:"status_industry"`
		ExcellentComments      []interface{} `json:"excellent_comments"`
		NoticeTag              interface{}   `json:"notice_tag"`
		CommonEmotion          interface{}   `json:"common_emotion"`
		CurrentStockPrice      interface{}   `json:"current_stock_price"`
		NewCard                interface{}   `json:"new_card"`
		SourceDeepLink         interface{}   `json:"source_deep_link"`
		SourceFeed             bool          `json:"source_feed"`
		Editable               bool          `json:"editable"`
		LikeConfig             interface{}   `json:"like_config"`
		TitleAdPic             interface{}   `json:"title_ad_pic"`
		TitleAdURL             interface{}   `json:"title_ad_url"`
		TitleAdDeepLink        interface{}   `json:"title_ad_deep_link"`
		AnswerComment          interface{}   `json:"answer_comment"`
		AnswerCount            int           `json:"answer_count"`
		AnswerUsers            interface{}   `json:"answer_users"`
		BonusScreenName        interface{}   `json:"bonus_screen_name"`
		FundxTag               interface{}   `json:"fundx_tag"`
		StockList              interface{}   `json:"stock_list"`
		ReplyUserImages        interface{}   `json:"reply_user_images"`
		ReplyUserCount         int           `json:"reply_user_count"`
		FundxSymbol            interface{}   `json:"fundx_symbol"`
		HotNewRank             interface{}   `json:"hot_new_rank"`
		ImageInfoList          interface{}   `json:"image_info_list"`
		RecommendCards         interface{}   `json:"recommend_cards"`
		IsAnswer               bool          `json:"is_answer"`
		IsRefused              bool          `json:"is_refused"`
		Text                   string        `json:"text"`
		ForbiddenRetweet       bool          `json:"forbidden_retweet"`
		CoverPic               string        `json:"cover_pic"`
		LegalUserVisible       bool          `json:"legal_user_visible"`
		IsColumn               bool          `json:"is_column"`
		ShowCoverPic           bool          `json:"show_cover_pic"`
		IsSsMultiPic           bool          `json:"is_ss_multi_pic"`
		IsBonus                bool          `json:"is_bonus"`
		VodInfo                interface{}   `json:"vod_info"`
		Pic                    string        `json:"pic"`
		IsOriginalDeclare      bool          `json:"is_original_declare"`
		MpNotShowStatus        bool          `json:"mp_not_show_status"`
		ForbiddenComment       bool          `json:"forbidden_comment"`
		AnswerQuestion         bool          `json:"answer_question"`
		IsNoArchive            bool          `json:"is_no_archive"`
		IsPrivate              bool          `json:"is_private"`
	} `json:"statuses"`
	Banner  interface{} `json:"banner"`
	Total   int         `json:"total"`
	Page    int         `json:"page"`
	MaxPage int         `json:"maxPage"`
}

// Description returns the description of the PrintJob.
func (pj *Xueqiu) Description() string {
	return pj.Desc
}

// Key returns the unique PrintJob key.
func (pj *Xueqiu) Key() int {
	return quartz.HashCode(pj.Description())
}

// Execute is called by a Scheduler when the Trigger associated with this job fires.
func (pj *Xueqiu) Execute() {
	// 执行函数体
	start_time := function.ExeStart()
	var result = map[string]interface{}{}

	core.Db.Debug().Table("bs_config").Where("`key`='xueqiu_cookie'").Find(&result)
	//cookie不存在
	if len(result) == 0 {
		alarm.DingDing("雪球cookie未设置")
	}

	cookie := utils.ToString(result["value"])

	var resultXueqiuCommentUser []model.BsXueqiuUser
	core.Db.Table("bs_xueqiu_user").Select("uid", "username", "is_need_push").Find(&resultXueqiuCommentUser)

	userChan := make(chan model.BsXueqiuUser, 10)
	if len(resultXueqiuCommentUser) != 0 {
		go func() {
			for _, item := range resultXueqiuCommentUser {
				userChan <- item
			}
			close(userChan)
		}()

		exitChan := make(chan bool, 10)
		for i := 0; i < 10; i++ {
			go InsertUgcTask(exitChan, userChan, cookie)
		}

		for i := 0; i < 10; i++ {
			<-exitChan
		}

	}

	pj.Signal <- true

	fmt.Println(2222222222)
	function.PrintUseTime(start_time)
}

func InsertUgcTask(exitChan chan bool, userChan chan model.BsXueqiuUser, cookie string) {
	for {
		userItem, ok := <-userChan

		if !ok {
			break
		}

		//获取当前用户所有的UGC列表
		var xueqiuUgcModel []model.XueqiuUgc
		core.Db.Table("bs_xueqiu_ugc").Where("uid = ?", userItem.Uid).Find(&xueqiuUgcModel)

		resultSlice, _ := function.StuctSliceToSliceByField(xueqiuUgcModel, "Xueqiuuid")

		url := fmt.Sprintf("https://xueqiu.com/v4/statuses/user_timeline.json?page=1&user_id=%s", userItem.Uid)

		token := utils.ToString(cookie)

		//生成cookie

		cookieMap := map[string]string{
			"xq_a_token": token,
			"device_id":  php2go.Md5(php2go.Uniqid(string(php2go.Rand(0, 10000)))),
		}

		makecookie := function.CookieMake(cookieMap)

		res := function.HttpRequestPostCookie(url, "", makecookie)

		var XueqiuComment AutoGenerated
		json.Unmarshal([]byte(res), &XueqiuComment)

		if XueqiuComment.Count != 0 {
			resList := XueqiuComment.Statuses
			if resList != nil {
				for _, item := range resList {
					text := item.Text
					id := item.ID

					if text == "" {
						continue
					}

					if !php2go.InArray(strconv.Itoa(id), resultSlice) {

						content := userItem.Username + "发布动态:"

						noNameText := function.TrimHtml(text)
						content += noNameText

						title := userItem.Username + "发布动态"

						defer func() {
							//捕获panic
							if err := recover(); err != nil {

								fmt.Println(function.PrintStackTrace())
								panic(err)
							}
						}()

						if userItem.IsNeedPush == int64(1) {
							queue.PushQueue("PushDingding", map[string]interface{}{
								"content": content,
								"title":   title,
							})
						}

						itemUidInt, _ := strconv.Atoi(userItem.Uid)
						core.Db.Debug().Table("bs_xueqiu_ugc").Create(&model.XueqiuUgc{
							Content:   noNameText,
							Xueqiuuid: id,
							Uid:       itemUidInt,
							CreatedAt: item.CreatedAt,
							Addtime:   php2go.Date("2006-01-02 15:04:05", php2go.Time()),
						})
					}

				}
			}
		} else {
			time.Sleep(120 * time.Second)
			fmt.Println(makecookie)
			fmt.Println(url)
			fmt.Println(res)
		}
	}
}
